<%@ tag language="java" pageEncoding="UTF-8" body-content="empty" trimDirectiveWhitespaces="true"%>
<%@ attribute name="id" type="java.lang.String" required='true' description="datatable的id"%>
<%@ attribute name="ajax" type="java.lang.String" required='true' description="请求datatable数据的ajax"%>
<%@ attribute name="pagination" type="java.lang.String" description="datatable的分页组件"%>
<%@ attribute name="sortable" type="java.lang.Boolean" description="是否启用排序，默认为false"%>
<%@ attribute name="checkable" type="java.lang.Boolean" description="是否启用复选框，默认为false"%>
<%@ attribute name="storage" type="java.lang.Boolean" description="是否启用本地存储来增强用户体验，默认为true"%>
<%@ attribute name="checkByClickRow" type="java.lang.Boolean" description="是否点击行的任意位置来切换选中状态 仅在checkable选项为true时生效，默认为true"%>
<%@ attribute name="single" type="java.lang.Boolean" description="是否单击行时单选，默认为false（多选）"%>
<%@	attribute name="border" type="java.lang.Boolean" description="是否显示表格边框，默认false"%>
<%@	attribute name="striped" type="java.lang.Boolean" description="隔行交替样式，默认false"%>
<%@	attribute name="widthAuto" type="java.lang.Boolean" description="将表格的宽度设置为auto，最大不超过100%，默认false"%>
<%@	attribute name="responsive" type="java.lang.Boolean" description="当设备屏幕宽度小于 768px 时，表格内容会禁用换行，当宽度不够时，允许在水平方向上进行滚动以浏览所有列，默认false"%>
<%@	attribute name="automatic" type="java.lang.Boolean" description="是否主动请求ajax，获取数据，默认为true"%>
<%@	attribute name="rowHover" type="java.lang.Boolean" description="是否在行上启用鼠标悬停样式，默认为true"%>
<%@	attribute name="colHover" type="java.lang.Boolean" description="是否在列上启用鼠标悬停样式，仅当鼠标悬停表头时生效，默认为true"%>
<%@ attribute name="dataSet" type="java.lang.String" required="false" description="指定表格的列定义，cols标签的id" %>
<%@ attribute name="cutLine" type="java.lang.Boolean" description="true时表格中文本过长则显示XXX...形式,默认false" %>
<%@ attribute name="tip" type="java.lang.Boolean" description="是否开启鼠标悬停提示，需先设置cutLine='true'，true(默认)|false" %>
<%@ attribute name="afterReady" type="java.lang.String" description="绑定ready事件，ready事件在渲染完毕后调用，可以在此事件中为DOM绑定其他事件"%>
<%@ attribute name="handleData" type="java.lang.String" description="ajax请求到数据后，处理数据的回调函数"%>
<%@ attribute name="afterLoad" type="java.lang.String" description="绑定afterLoad事件：onAfterLoad(event)，afterLoad事件在数据加载完毕后调用"%>
<%@ attribute name="afterSort" type="java.lang.String" description="绑定afterSort事件：afterSort(event)，afterSort事件在排序结束后调用"%>
<%@ attribute name="onChecksChanged" type="java.lang.String" description="绑定onChecksChanged事件：onChecksChanged(checksRecord,checkAll,currentRecord)，afterChecksChanged事件在选中状态发生改变时触发，需checkable开启"%>
<%@ attribute name="onRenderItem" type="java.lang.String" description="渲染数据时的事件，要求返回一个字符串作为这一数据的html代码，也可以是一个文本数据(用于插入&lt;td&gt;标签中)：onRenderItem(colName,text,indexStr,mItem)"%>
<%@ attribute name="onDoubleClick" type="java.lang.String" description="绑定数据表格行双击事件" %>
<%@ attribute name="onSingleClick" type="java.lang.String" description="绑定表格行单击事件，针对ckeckable未开启时，若checkable开启，则设置onChecksChanged即可"%>
<div id="${id}" data-checkable='${checkable}' class="datatable" data-storage="${storage}" data-sortable='${sortable}' data-checkByClickRow='${checkByClickRow}' data-single='${single}'></div>
<script type="text/javascript">
(function(){
	var opt = {
		'datatable':{}
	};
	var _this = opt.datatable["${id}"] = {};
	//属性
	var ajax = window["${ajax}"];
	var succFunc = ajax.succFunc;
	
	// 实例化一个DataSet的对象
	var id = "${id}";
	var automatic = "${automatic}" == "" ? true : "${automatic}" == "true"; // 是否主动从ajax获取数据，默认为true
	_this.dataset = window[id] = new DataSet(id,ajax,automatic);
	var border = "${border}";
	if(border == 'true'){
		$("#"+id).addClass("table-bordered"); 
	}
	if("${striped}" == 'true'){
		$("#"+id).addClass("table-striped");
	}
	if("${widthAuto}" == 'true'){
		$("#"+id).addClass("table-auto");
	}
	if("${responsive}" == 'true'){
		$("#"+id).addClass("table-responsive");
	}
	
	// 事件
	var readyFunc = "${afterReady}"=="" ? undefined: eval("${afterReady}");
	var afterLoadFunc = "${afterLoad}"=="" ? undefined: eval("${afterLoad}");
	var afterSortFunc = "${afterSort}"=="" ? undefined: eval("${afterSort}");
	var onChecksChangedFunc = "${onChecksChanged}"=="" ? undefined: eval("${onChecksChanged}");
	var onRenderItemFunc = "${onRenderItem}"=="" ? undefined: eval("${onRenderItem}");
	var handleDataFunc = "${handleData}"=="" ? undefined: eval("${handleData}");
	//行双击
	var onDoubleClickFunc = "${onDoubleClick}"=="" ? undefined: eval("${onDoubleClick}");
	var onSingleClickFunc = "${onSingleClick}"==""?undefined:eval("${onSingleClick}");
	//数据集
	var cols = window["${dataSet}"];
	//悬停样式
	var rowHover = "${rowHover}"==""?true:"${rowHover}"!="false";
	var colHover = "${colHover}"==""?true:"${colHover}"!="false";
	/* 用于数据的后端排序，取消
	$("div #"+"${pagination}"+" input[name='colSort']").remove();
	$("div #"+"${pagination}").append("<input type=\"hidden\" name=\"colSort\" />");
	$("div #"+"${pagination}"+" input[name='colSort']").val(cols.getSort()); */
	
	// 获取分页插件
	var getPagination = function (dataset) {
		if (dataset.pagination == null) {
			var pagination = window["${pagination}"];
			dataset.pagination = pagination;
		}
	};
	// 重写ajax的send方法
	ajax.osend = ajax.send;
	ajax.send = function(reset) {
		getPagination(_this.dataset);
		if (reset == null || reset == true) {
			_this.dataset.pagination && _this.dataset.pagination.resetPagination();
		}
		ajax.osend();
	};
	
	ajax.bindSuccessEvent(function(re,status,xhr){
		if (handleDataFunc){
			handleDataFunc(re);
		}
		_this.data = re;
		//cols为null，表示采用后端定义列
		if(cols != null && cols != 'undefined'){
			// 兼容先前的版本
			var mCount = (re.info && re.info.count) || re.total;
			var mData = (re.info && re.info.data) || re.rows;
			// 实例化TableInfo得到数据
			_this.data = new TableInfo(re.isSuccess,mCount);
			_this.data.setColsRows(cols.getCols(),mData);
		}
		_this.dataset.setJsonData(_this.data); // 将数据存储到dataset实例中
		// 回调函数中，可以肯定分页组件已经被实例化了
		if (!StringUtil.isEmpty("${pagination}")){
			getPagination(_this.dataset);
			_this.dataset.pagination.count = _this.data.count;
			_this.dataset.pagination.refresh(false); // 刷新分页条，不重新请求数据
		}
		// 启用渲染表格数据
		$("#"+id).datatable({
			rowHover:rowHover,
			colHover:colHover,
			// 设置数据
			data: _this.data.dataset,
			// 数据加载完毕后调用
			afterLoad:function(event){
				// event.data 表格数据
				afterLoadFunc && afterLoadFunc(event);
			},
			// 渲染完毕后调用，可以在此事件中为DOM绑定其他事件
			ready:function(){
				// 只有注册了此回调函数才会去循环遍历
				Logger.info("datatable.tag => datatable.id = ${id}, is on ready");
				if(onRenderItemFunc && (onRenderItemFunc instanceof Function)){
					$("#${id} td[data-index]").each(function(){
						var indexStr = $(this).attr("data-index");
						var rowIndex = $(this).closest("tr").data("index");
						var re = new RegExp(/^[0-9]*[0-9][0-9]*$/);
						if(indexStr.match(re)!=null) {
							index = parseInt(indexStr);
							var colName = _this.dataset.cols[index].name;
							var text = $(this).text();
							var mItem = _this.dataset.records[rowIndex].data; // 每行的数据，key,value形式提供
							var html = onRenderItemFunc(colName,text,indexStr,mItem);
							html && $(this).html(html);
						}
					});
				}
				
				readyFunc && readyFunc();
			},
			// 表格重新排序之后
			// event.sorter.index 数字，排序所依据的列序号 event.sorter.sortUp 排序方向，true为升序，false 为降序
			sort:function(event){
				afterSortFunc && afterSortFunc(event);
			},
			// 列宽发生更改时发生
			// event.changes.change 字符串，变化的类型，"fixedLeftWidth" 为左侧所有固定列总宽度发生变化，
			// "fixedRightWidth" 为右侧所有固定列总宽度发生变化，"colWidth" 为单个列宽度
			// 发生变化 event.changes.oldWidth 数字，发生变化之前的宽度值 event.changes.newWidth 数字，
			// 新的宽度值 event.changes.colIndex 数字，如果是单个列宽发生变化，则该值指示发生变化列的序号
			sizeChanged:function(event){
				
				
			},
			// 当行的选中状态发生变化时发生
			// event.checks.checkedAll 如果为true 标识当前所有行都被选中，反之则表示至少有一行为被选
			// 中 * event.checks.checks 数字数组，包含所有已选中的行的ID
			checksChanged:function(e){
				var checkedRecordIdArray = e.checks.checks;
				_this.dataset._setSelectedRecords(checkedRecordIdArray);
				var checkAll = e.checks.checkedAll;
			//	var checksArr = e.checks.checks ? e.checks.checks.toString().split(","):[];
			//	var currentCheckedId =  checksArr[0];
			//	_this.dataset._setCurrentRecord(currentCheckedId);
				// record的结构：
				// 		record : {id:xxx,data:{这里面才是用户所想要的数据}}
				var checksRecord = _this.dataset.getSelectedRecords();
				var checksDataArr = new Array();
				if(checksRecord && checksRecord.length>0){
					for(var i=0;i<checksRecord.length;i++) {
						checksDataArr.push(checksRecord[i].data);
					}
				}
				var currentRecord = _this.dataset.getCurrentRecord();
				var currData = currentRecord && currentRecord.data;
				
				try{
					onChecksChangedFunc && onChecksChangedFunc(checksDataArr,checkAll,currData);
				}catch(e){
					Logger.error("执行onChecksChanged回调时失败：" + e);
					Logger.info("-----------------------------------------");
					Logger.info("是否全选: " + checkAll);
					Logger.info("你总共选中的数据: " + JSON.stringify(checksDataArr));
					Logger.info("你最新选中的数据的current data: " + JSON.stringify(currData));
					Logger.info("-----------------------------------------");
				}
				
			}
		});
		succFunc && succFunc(re,status,xhr);
		var tbodyLen = $("#"+id+" tbody tr").length;
		//行双击事件绑定
		if(onDoubleClickFunc != undefined && tbodyLen != 0){
			$("#"+id+" tbody tr").dblclick(function(){
				var rowNum =  $(this).index();	//行号，即row id
				_this.dataset._setCurrentRecord(rowNum);
				onDoubleClickFunc && onDoubleClickFunc();
			});
		}
		//行单击事件
		// single(有复选框，但不支持多选，在checkable=true时有效),checkable(支持多选，出现复选框)
		// if single=true and checkable=true then onSingleClickFunc can be exec
		// if checkable = false then onSingleClickFunc can be exec
		_this.single = "${single}"==""?false:"${single}"=="true";
	//	if(onSingleClickFunc != undefined && _this.single && tbodyLen != 0){
		if(tbodyLen != 0){
			$("#"+id+" tbody tr").click(function(){
				var rowNum =  $(this).index();	//行号，即row id
				_this.dataset._setCurrentRecord(rowNum);
				if(onSingleClickFunc != undefined && _this.single){
					onSingleClickFunc && onSingleClickFunc();
				}
			});
		}
		//数据为空时格式
		if(tbodyLen == 0){
			_this.colspan = cols.arr.length;
			var tr = '<tr data-index="0" data-id="0" class="">'+
							'<td colspan="'+_this.colspan+'" align="center">未找到相关数据</td>'
					+'</tr>';
			$("#"+id+" tbody").append(tr);
		}
		// 针对Chrome 39，解决分页条位置错乱的Bug-20170117-lj
		if($("#${pagination}")[0]){
			$("#${pagination}").css("-webkit-transform","translateZ(0)"); // -webkit-transform: translateZ(0);
		}
		//超出表格长度文本处理
		var cutLine = "${cutLine}"==""?false:"${cutLine}"=="true";
		var tip = "${tip}"==""?true:"${tip}"=="true";
		if(cutLine){
			$("#"+id+" table").addClass("table-ellipsis");
			$("#"+id+" table td").addClass("table-td-ellipsis");
			var fontSize = $("#"+id+" table td:eq(0)").css('height');
			$("#"+id+" tbody td").each(function(){
				if(tip){
					$(this).attr('title',$(this).text());
				}
				var len = $(this).css('height');
				fontSize = parseInt(len.substring(0,len.length-2))
					<parseInt(fontSize.substring(0,fontSize.length-2))?len:fontSize;
			});
			if(parseInt(fontSize.substring(0,fontSize.length-2))<37){
				fontSize = "37px";
			}
		//	if($("#"+id+" tbody tr").length == 1){
				fontSize = "37px";
		//	}
			$("#"+id+" table td").css("height",fontSize); 
			$("#"+id+" table td").css("min-height",fontSize);
		}else{	//支持英文数字换行
			$("#"+id+" table").addClass("table-Wrap");
		
			var fontSize = $("#"+id+" table td:eq(0)").css('height');
			$("#"+id+" tbody td").each(function(){ 
					var len = $(this).css('height');
					fontSize = parseInt(len.substring(0,len.length-2))
						>parseInt(fontSize.substring(0,fontSize.length-2))?len:fontSize;
			});
			$("#"+id+" table td").css("height",fontSize); 
		}  
	});
	Logger.info("datatable:${id}初始化完毕");
	if (StringUtil.isEmpty("${pagination}") && automatic) {
		// 当没有分页条时，要求datatable能够自动发送ajax
		ajax.send();
	}
})();
</script>